﻿using System;
using System.Collections.Generic;
using System.IO;

using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Win32;
using MapSurface.UIModelElement;
using MapSurface.Engine;
using MapSurface.WidgetSurface;
using System.Windows.Markup;


namespace MapSurfaceGUIChoice
{
    ///  <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {

        #region Initialize SurfaceWindow
        /// <summary>
        /// Default constructor.
        /// </summary>
        public SurfaceWindow1()
        {
            InitializeComponent();

            // Add handlers for Application activation events
            AddActivationHandlers();
            //C:\Users\Nepthys\Documents\Andre\workspace1
            //C:\Users\André\Documents\Visual Studio 2008\Projects
            if (IntPtr.Size == 4)
                dllDir = @"C:\Users\André\Documents\These\workspace1\mapsurface\MAPSurfaceGUIActive\Assembly";
            else if (IntPtr.Size == 8)
                dllDir = @"\Assembly";
            loadModelinList(@"C:\Users\André\Documents\These\workspace1\mapgui\models\ui");
            apiFile = @".\Resources\APIModelXAML_TS.xmi";
        }
        public object uiRoot = null;
        public Object selectElement = null;
        private bool editMode = true;
        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here
        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }
        #endregion

        #region Handlers
        private void ExplorerList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
        private void DeleteElement_Click(object sender, RoutedEventArgs e)
        {

        }
        private void Deselect_Click(object sender, RoutedEventArgs e)
        {
            labelTypeValue.Content = "";
            labelNameValue.Content = "";
            labelHValue.Content = "";
            labelWValue.Content = "";
            DeleteElement.IsEnabled = false;
            Deselect.IsEnabled = false;
            EditElements.IsEnabled = false;
            Organize.IsEnabled = false;
            Choice.Visibility = Visibility.Hidden;
            try
            {
                if (selectElement != null)
                {
                    foreach (BorderElement b in BorderElement.BorderCollection)
                    {
                        if(b.wr.CanResize)
                        {
                            b.setBorderNotVisible();
                            selectElement = null;
                            b.wr.CanResize = false;
                            b.wm.CanMove = false;
                           
                        }

                    }
                    selectElement = null;
                }
            }
            catch (Exception) { }

        }
        private void ArrangeLayout_Click(object sender, RoutedEventArgs e)
        {
            DesignSpace.Children[0]= (System.Windows.UIElement) updateChild(DesignSpace.Children[0],modelLoader.Assembly);
        }
        private void Arrange_Click(object sender, RoutedEventArgs e)
        {
            if(selectElement!=null)
                selectElement = (System.Windows.UIElement)updateChild(selectElement, modelLoader.Assembly);
        }
        private void EditMode_Click(object sender, RoutedEventArgs e)
        {
           
            foreach (BorderElement b in BorderElement.BorderCollection)
            {
                b.setEditMode(!editMode);
            }
            if (editMode)
                Preview.Content = "Edit Mode";
            else
                Preview.Content = "Preview ...";
            editMode = !editMode;

        }
        public object updateChild( object parent, MapSurface.AssemblyReflexion.AssemblyReflexion ass )
        {
            if (parent != null)
            {
                List<object> childs = ass.getChild(parent);
                if (parent.GetType() == typeof(BorderElement) && ((BorderElement)parent).Content.Children.Count > 0)
                    childs = ass.getChild(((BorderElement)parent).Content.Children[0]);
                if (childs != null)
                {
                    for (int i = 0; i < childs.Count; i++)
                    {
                        object o = childs[i];
                        childs[i] = updateChild(o, ass);
                    }
                    if (parent.GetType() == typeof(BorderElement) && ((BorderElement)parent).Content.Children.Count > 0)
                        ((BorderElement)parent).Content.Children[0] = (System.Windows.UIElement)ass.defineLayout(((BorderElement)parent).Content.Children[0]);
                }
            }
            return parent;
        }
        public object updateAllChild(object parent, MapSurface.AssemblyReflexion.AssemblyReflexion ass)
        {
            return parent;
        }

        public void sizeChanged(object sender, EventArgs e)
        {
            if (selectElement != null)
            {
                displayPropertie(selectElement);
            }
        }

        #endregion

        #region Model Loader
        public UIModelChoiceLoader modelLoader = null;

        private void loadModel(string modelFile)
        {
            if (modelFile.CompareTo(SelectedPath) == 0)
            {
                modelLoader.setLoader(SelectedPath, dllDir,SelectTable);

            }else
            {
                SelectedPath = modelFile;
                modelLoader = new UIModelChoiceLoader(SelectedPath, dllDir, SelectTable,apiFile);

            }
            this.DesignSpace.Children.Clear();
            BorderElement.resetBorderElement();
            if (selectElement != null)
                Deselect_Click(selectElement, null);

            modelLoader.Assembly.RoutedEvent.Add(Microsoft.Surface.Presentation.Contacts.ContactTapGestureEvent);
            modelLoader.Assembly.SelectEventHandler.Add(new Microsoft.Surface.Presentation.ContactEventHandler(this.ChoiceElement));
            modelLoader.Loader.DesignSpace = DesignSpace;
            List<Object> list = modelLoader.process(this);
            foreach (BorderElement be in BorderElement.BorderCollection)
            {
                be.myUISelector += new BorderElement.SelectUIhandler(selectUIElement);
                be.addhandler();
            }
            foreach (object o in list)
            {
                if (o != null)
                {
                    //Console.WriteLine(XamlWriter.Save(o));
                    this.DesignSpace.Children.Add((System.Windows.UIElement)o);
                }
            }
            //Console.Out.WriteLine(list[0].ToString());
            ArrangeLayout.IsEnabled = true;
            Preview.IsEnabled = true;
        }

        private void loadModelinList(string dir)
        {
            List<SurfaceListBoxItem> li = UIModelLoader.loadFile(dir);
            foreach (SurfaceListBoxItem i in li)
                ExplorerList.Items.Add(i);
        }

        private void SurfaceListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            loadModel(((SurfaceListBoxItem)((SurfaceListBox)sender).SelectedItem).ContentStringFormat);
            SelectFile.Visibility = Visibility.Hidden;
        }

        #endregion

        #region File Chooser
        private string _selectedPath;
        public string SelectedPath
        {
            get
            {
                return _selectedPath;
            }

            set
            {
                _selectedPath = value;
            }
        }
        public string SelectTable
        {
            get
            {
                if (SelectedPath != null)
                {
                   
                    string[] tab = _selectedPath.Split('\\');
                    tab[tab.Length - 2] = "equi";
                    string ret = "";
                    for (int i = 0; i < tab.Length - 1; i++)
                        ret += tab[i] + "\\";
                    return ret + tab[tab.Length-1];
                }
                return null;
            }
        }
        private string apiFile = "";

        private void OnBrowseButtonClick(object sender, RoutedEventArgs e)
        {
            FileDialog dialog = this.CreateFileDialog();
            if (dialog == null)
            {
                return;
            }

            if (File.Exists(this.SelectedPath))
            {
                dialog.FileName = this.SelectedPath;
            }

            dialog.Filter = "XML Files (*.xmi)|*.xmi";
            bool? result = dialog.ShowDialog();
            if (result == true)
            {
                this.SelectedPath = dialog.FileName;
            }
        }
        public enum FileChooserMode
        {
            Open,
            Save
        }
        FileChooserMode fc = FileChooserMode.Open;
        private string dllDir = "";
        protected FileDialog CreateFileDialog()
        {
            switch (fc)
            {
                case FileChooserMode.Open:
                    return new OpenFileDialog();
                case FileChooserMode.Save:
                    return new SaveFileDialog();
                default:
                    return null;
            }
        }
        private void SurfaceButton_Click(object sender, RoutedEventArgs e)
        {
            if (!SelectFile.IsVisible)
                SelectFile.Visibility = Visibility.Visible;
        }
        #endregion

        #region UIOperations

        public void selectUIElement(object sender)
        {
            if (sender != null && editMode)
            {
                selectElement = sender;
                Deselect.IsEnabled = true;
                EditElements.IsEnabled = true;
                Organize.IsEnabled = true;
                displayPropertie(sender);
                try
                {
                    if (((System.Windows.FrameworkElement)selectElement).Parent != null)
                    {
                        foreach (BorderElement b in BorderElement.BorderCollection)
                        {
                            if (b.Content.Children.Contains((System.Windows.UIElement)selectElement))
                            {
                                b.setBorderVisible();
                                b.wr.CanResize = true;
                                b.wm.CanMove = true;
                                b.wr.displayProp += displayPropertie;
                                b.wm.MainCanvas = DesignSpace;
                                //((System.Windows.UIElement)selectElement).RemoveHandler(ContactTapGestureEvent,new ContactEventHandler( this.ChoiceElement));
                                b.wm.connectMouseHandlers((System.Windows.UIElement)selectElement);
                                //((System.Windows.UIElement)b.Content.Children[0]).RemoveHandler(ContactTapGestureEvent, new ContactEventHandler(this.ChoiceElement));

                                break;
                            }

                        }
                    }
                    else Deselect_Click(null, null);
                }
                catch (Exception  )
                {
                }
            }
        }

        private void displayPropertie(object uiElement)
        {
            labelTypeValue.Content = uiElement.GetType().Name;
            labelNameValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Name");
            if (string.Compare(labelNameValue.Content.ToString(), "") == 0)
                labelNameValue.Content = modelLoader.Assembly.getAttribute(uiElement, "Content"); //DesiredSize
            Object size = modelLoader.Assembly.getAttribute(uiElement, "RenderSize");
            if (size != null)
            {
                string[] s = size.ToString().Split(';');
                if (s.Length < 2)
                    s = size.ToString().Split(',');
                labelWValue.Content = s[0];
                labelHValue.Content = s[1];
            }
            DeleteElement.IsEnabled = true;
        }
        
        private void EditElements_Click(object sender, RoutedEventArgs e)
        {
            if (selectElement != null && modelLoader.Manager.Model!=null)
            {
                ChoiceUIElement.Children.Clear();
                List<Object> li = modelLoader.getChoiceElement(selectElement);
                int row=0;
                if(li!=null && li.Count>0)
                {
                    foreach (object o in li)
                    {
                        if (o != null)
                        {
                            Label t = new Label();
                            t.Content = o.GetType().Name;
                            t.ContentStringFormat = o.GetType().Name;
                            Grid.SetRow((System.Windows.UIElement)o, row);
                            Grid.SetColumn((System.Windows.UIElement)o, 1);
                            Grid.SetRow((System.Windows.UIElement)t, row);
                            Grid.SetColumn((System.Windows.UIElement)t, 0);
                            ChoiceUIElement.Children.Add((System.Windows.UIElement)o);
                            ChoiceUIElement.Children.Add((System.Windows.UIElement)t);
                            
                            ReplaceButton button = new ReplaceButton("Replace", ChoiceUIElement,o, new ReplaceButton.ModelHandler(modelLoader.Loader.replaceObject), new ReplaceButton.SelectElement(selectUIElement), selectElement);
 
                            button.rootUI = this.DesignSpace;
                            Grid.SetColumn((System.Windows.UIElement)button, 2);
                            Grid.SetRow((System.Windows.UIElement)button, row);
                            ChoiceUIElement.Children.Add(button);
                            SurfaceCheckBox scb = new SurfaceCheckBox();
                            scb.Name = "All" + row;
                            scb.IsChecked = false;
                            Grid.SetColumn((System.Windows.UIElement)scb, 3);
                            Grid.SetRow((System.Windows.UIElement)scb, row);
                            ChoiceUIElement.Children.Add(scb);

                            button.myLabel = t;
                            if (ChoiceUIElement.Resources["All" + row] != null)
                                ChoiceUIElement.Resources.Remove("All" + row);
                            ChoiceUIElement.Resources.Add("All" + row, scb);
                            row++;

                        }
                    }
                    Choice.Visibility = Visibility.Visible;
                }
            }
        }

        public void ChoiceElement(object sender,RoutedEventArgs e)
        {
            if (selectElement == null)
            {
                selectUIElement(sender);
                try
                {
                    ((ContactEventArgs)e).Handled = true;
                }
                catch (Exception)
                {
                    ((RoutedEventArgs)e).Handled = true;
                }
            }
            else if (sender.GetHashCode() == selectElement.GetHashCode())
                try
                {
                    ((ContactEventArgs)e).Handled = true;
                }
                catch (Exception)
                {
                    ((RoutedEventArgs)e).Handled = false;
                }
            else if (selectElement != null)
            {
                Deselect.IsEnabled = true;
                try
                {
                    ((ContactEventArgs)e).Handled = false;
                }
                catch (Exception)
                {
                    ((RoutedEventArgs)e).Handled = false;
                }

            }

        }

        private void RemoveElement(object sender, RoutedEventArgs e)
        {
        }

        #endregion

    }
}